package atomic;

import org.junit.Test;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicMarkableReference;

/**
 * @author <a href='https://gitee.com/hzf2281'>codefish</a>
 * @version 1.0.0
 * @since 2022/08/20 下午 01:54
 */
public class AtomicTest {

    @Test
    public void atomicIntegerTest() {
        AtomicInteger atomicInteger = new AtomicInteger();
        System.out.println(atomicInteger.compareAndSet(0, 10));//true
        System.out.println(atomicInteger.get());//10
        System.out.println(atomicInteger.incrementAndGet());//11
        System.out.println(atomicInteger.addAndGet(5));//16
    }

    @Test
    public void atomicIntegerArrayTest() {
        AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);//初始化时需要指定数组长度
        //相比于基本类型原子类在进行操作时需要指定下标
        System.out.println(atomicIntegerArray.compareAndSet(5, 0, 10));
        System.out.println(atomicIntegerArray.get(5));// 10
        System.out.println(atomicIntegerArray.incrementAndGet(5));// 11
    }

    @Test
    public void atomicMarkableReferenceTest() {

        AtomicMarkableReference<Integer> reference = new AtomicMarkableReference<>(233, false);
        new Thread(() -> {
            Integer x = reference.getReference();
            try {
                TimeUnit.MILLISECONDS.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(reference.compareAndSet(x, x, false, true));
        }, "t1").start();

        new Thread(() -> {
            Integer x = reference.getReference();
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(reference.compareAndSet(x, x, false, true));
        }, "t2").start();

        new Thread(() -> {
            Integer x = reference.getReference();
            try {
                TimeUnit.MILLISECONDS.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(reference.compareAndSet(x, x, false, true));
        }, "t3").start();
   
        try { TimeUnit.MILLISECONDS.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }
         //线程t2先执行完，将mark从false改成了true，其它线程cas操作都失败
        System.out.println(reference.getReference());
    }


}
